package com.kmb.commons.utils;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * Http工具类 支持get post请求
 * </p>
 * 基于httpClient
 */
public class HttpUtils {
    private static final Logger LOGGER = LoggerFactory.getLogger(HttpUtils.class);
    private static final int NUMBER_OF_CACHE = 4096;

    /**
     * 获取绝对路径
     * @return
     */
    public static String getContextPath(){
        WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
        return webApplicationContext.getServletContext().getContextPath();
    }

    /**
     * get请求，返回值根据实际情况解析
     *
     * @param header
     * @param url
     * @return
     */
    public static String httpGet(Map<String, String> header, String url) {
        // 创建http客户端
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 设置请求
        HttpGet httpGet = new HttpGet(url);
        // 设置头部
        if (null != header && !header.isEmpty()) {
            for (String key : header.keySet()) {
                httpGet.setHeader(key, header.get(key));
            }
        }
        // 发起请求
        CloseableHttpResponse response = null;
        InputStream inputStream = null;
        String returnStr = "";
        try {
            response = httpClient.execute(httpGet);

            inputStream = response.getEntity().getContent();
            returnStr = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
        } catch (IOException e) {
            LOGGER.error("异常", e);
        } finally {
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                    LOGGER.error("关闭输入流异常", e);
                }
            }
            if (null != response) {
                try {
                    response.close();
                } catch (Exception e) {
                    LOGGER.error("关闭HTTP链接异常");
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (Exception e) {
                    LOGGER.error("关闭HTTP链接异常");
                }
            }
        }

        return returnStr;
    }

    /**
     * post请求,返回值根据实际情况解析
     *
     * @param header
     * @param url
     * @return
     */
    public static File httpGetToFile(Map<String, String> header, String url, OutputStream out) {
        // 创建http客户端
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 设置请求
        HttpGet httpGet = new HttpGet(url);
        // 设置头部
        if (null != header && !header.isEmpty()) {
            for (String key : header.keySet()) {
                httpGet.setHeader(key, header.get(key));
            }
        }

        // 发起请求
        CloseableHttpResponse response = null;
        InputStream inputStream = null;

        File returnFile = null;
//        OutputStream out = null;
        try {
            response = httpClient.execute(httpGet);

            inputStream = response.getEntity().getContent();
//            returnFile = File.createTempFile("temp", null);
//            out = new FileOutputStream(returnFile);

            byte[] data = new byte[NUMBER_OF_CACHE];
            int count;
            while ((count = inputStream.read(data)) != -1) {
                out.write(data, 0, count);
            }
        } catch (IOException e) {
            LOGGER.error("异常", e);
        } finally {
            if (null != out) {
                try {
                    out.close();
                } catch (Exception e) {
                    LOGGER.error("关闭输出流异常", e);
                }
            }
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                    LOGGER.error("关闭输入流异常", e);
                }
            }
            if (null != response) {
                try {
                    response.close();
                } catch (Exception e) {
                    LOGGER.error("关闭HTTP链接异常");
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (Exception e) {
                    LOGGER.error("关闭HTTP链接异常");
                }
            }
        }

        return returnFile;
    }

    /**
     * post请求,返回值根据实际情况解析
     *
     * @param header
     * @param body   body根据业务需求进行组装
     * @param url
     * @return
     */
    public static String httpPost(Map<String, String> header, HttpEntity body, String url) {
        // 创建http客户端
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 设置请求
        HttpPost httpPost = new HttpPost(url);
        // 设置头部
        if (null != header && !header.isEmpty()) {
            for (String key : header.keySet()) {
                httpPost.setHeader(key, header.get(key));
            }
        }
        // 设置body
        if (null != body) {
            httpPost.setEntity(body);
        }

        // 发起请求
        CloseableHttpResponse response = null;
        InputStream inputStream = null;
        String returnStr = "";
        try {
            response = httpClient.execute(httpPost);

            inputStream = response.getEntity().getContent();
            returnStr = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
        } catch (IOException e) {
            LOGGER.error("异常", e);
        } finally {
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                    LOGGER.error("关闭输入流异常", e);
                }
            }
            if (null != response) {
                try {
                    response.close();
                } catch (Exception e) {
                    LOGGER.error("关闭HTTP链接异常");
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (Exception e) {
                    LOGGER.error("关闭HTTP链接异常");
                }
            }
        }

        return returnStr;
    }
}
